package com.visionblue.business.ship.modbus.utilities

import com.visionblue.business.ship.util.formatHex4Bits
import kotlin.math.pow

/**
 * 瞬时流量计算
 */
fun ieee754(int1: Int,int2: Int,int3: Int,int4: Int): Double {
    // S－尾数的符号；1＝负数,0 = 正数
    val s = int1.shr(7).toUInt()
    val e_l = int1 and 0x7F
    val i = int2 and 0x80

    // E－指数；与十进制数 127 的差值表示。
    var e:UInt? = null
    if (i.ushr(7) == 0) {
         e = e_l.shl(1).toUInt()
    }else{
         e = (e_l.shl(1) or 0x01).toUInt()
    }

    // M－尾数；低 23 位，小数部分。
    var m = 0.0

    // 低7位
    for (bit in 6 downTo 0) {
        val bitVal = int2 shr bit and 0x1
        val magnitude = 1 / (2.0.pow(7 - bit))
        m += bitVal * magnitude
    }

    for (bit in 7 downTo 0) {
        val bitVal = int3 shr bit and 0x1
        val magnitude = 1 / (2.0.pow(15 - bit))
        m += bitVal * magnitude
    }

    for (bit in 7 downTo 0) {
        val bitVal = int4 shr bit and 0x1
        val magnitude = 1 / (2.0.pow(23 - bit))
        m += bitVal * magnitude
    }
    return iee754(s.toInt(), e.toInt(), m)
}

fun calculate(int1: Int,int2: Int,int3: Int,int4: Int) :Long{
    val int_1 = int1.toString(16)
    val hex4Bits1 = formatHex4Bits(int_1)
    val int_2 = int2.toString(16)
    val hex4Bits2 = formatHex4Bits(int_2)
    val int_3 = int3.toString(16)
    val hex4Bits3 = formatHex4Bits(int_3)
    val int_4 = int4.toString(16)
    val hex4Bits4 = formatHex4Bits(int_4)

    val hex = hex4Bits1 + hex4Bits2 + hex4Bits3 + hex4Bits4
    var result = 0L
    hex.toUpperCase().withIndex().forEach {
        val index = 7 - it.index
        val prefix = if (it.value.isDigit()) {
            it.value - '0'
        } else {
            it.value - 'A' + 10
        }
        result += (prefix) * (16.0.pow(index)).toLong()
    }
    return result
}

/**
 * @author: xlh - 废机油转换逻辑
 * @date: 2020-06-10 7:00 PM
 * @desc:
 */
fun floatInverse(results: IntArray, low: Int, high: Int): Double {
    // S－尾数的符号；1＝负数,0 = 正数
    val s = results[low] shr 15
    // E－指数；与十进制数 127 的差值表示。
    val e = results[low] shr 7 and 0xff
    // M－尾数；低 23 位，小数部分。
    val m = decimal(results[low] and 0x7f, results[high])
    return iee754(s, e, m)
}

fun longInverse(results: IntArray, low: Int, high: Int): Long {

    val lowHex = results[low].toString(16)
    val highHex = results[high].toString(16)

    val lowHex4Bits = formatHex4Bits(lowHex)
    val highHex4Bits = formatHex4Bits(highHex)

    val finalHex = lowHex4Bits + highHex4Bits
    var calcResult = 0L

    /*   CrashReport.postCatchedException(
           Exception("low = ${results[low]}, high = ${results[high]}, lowHex = $lowHex, highHex = $highHex, finalHex = $finalHex")
       )*/

    finalHex.toUpperCase().withIndex().forEach {
        val index = 7 - it.index
        val prefix = if (it.value.isDigit()) {
            it.value - '0'
        } else {
            it.value - 'A' + 10
        }
        calcResult += (prefix) * (16.0.pow(index)).toLong()
    }

    return calcResult
}


private fun iee754(s: Int, e: Int, m: Double): Double {
    return ((-1.0).pow(s)) * ((2.0).pow(e - 127)) * (1 + m)
}

// - 00110110
// - 11011001 10011010
private fun decimal(low: Int, high: Int): Double {
    var result = 0.0
    // 低7位
    for (bit in 6 downTo 0) {
        val bitVal = low shr bit and 0x1
        val magnitude = 1 / (2.0.pow(7 - bit))
//            MLog.e("bit = $bit, bitVal = $bitVal, magnitude = $magnitude, bitVal * magnitude = ${bitVal * magnitude}")
        result += bitVal * magnitude
    }

    // 高16位
    for (bit in 15 downTo 0) {
        val bitVal = high shr bit and 0x1
        val magnitude = 1 / (2.0.pow(23 - bit))
//            MLog.e("bit = $bit, bitVal = $bitVal, magnitude = $magnitude, bitVal * magnitude = ${bitVal * magnitude}")
        result += bitVal * magnitude
    }

    return result
}